package simonby.top.annualring.adapter.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import simonby.top.annualring.application.service.UserFamilyApplicationService;
import simonby.top.annualring.application.service.PermissionApplicationService;
import simonby.top.annualring.domain.model.UserFamily;
import simonby.top.annualring.adapter.dto.UserFamilyDTO;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户家族关联控制器
 * 处理用户与家族关联关系的HTTP请求
 */
@RestController
@RequestMapping("/api/user-families")
public class UserFamilyController {
    private final UserFamilyApplicationService userFamilyApplicationService;
    private final PermissionApplicationService permissionApplicationService;

    public UserFamilyController(UserFamilyApplicationService userFamilyApplicationService,
                               PermissionApplicationService permissionApplicationService) {
        this.userFamilyApplicationService = userFamilyApplicationService;
        this.permissionApplicationService = permissionApplicationService;
    }

    /**
     * 创建用户家族关联关系（添加成员到家族树）
     * @param userFamilyDTO 用户家族关联DTO
     * @return 创建后的关联关系DTO
     */
    @PostMapping
    public SaResult createUserFamily(@RequestBody UserFamilyDTO userFamilyDTO) {
        // 检查当前用户是否有权限管理该家族树
        if (!permissionApplicationService.canManageFamilyTree(userFamilyDTO.getFamilyTreeId())) {
            return SaResult.error("无权限执行此操作");
        }
        
        UserFamily userFamily = convertToDomain(userFamilyDTO);
        UserFamily savedUserFamily = userFamilyApplicationService.createUserFamily(userFamily);
        return SaResult.ok("添加成功").setData(convertToDTO(savedUserFamily));
    }

    /**
     * 根据ID获取用户家族关联关系
     * @param id 关联ID
     * @return 用户家族关联DTO
     */
    @GetMapping("/{id}")
    public UserFamilyDTO getUserFamilyById(@PathVariable Long id) {
        return userFamilyApplicationService.getUserFamilyById(id)
                .map(this::convertToDTO)
                .orElse(null);
    }

    /**
     * 根据用户ID获取关联的家族树
     * @param userId 用户ID
     * @return 用户家族关联DTO列表
     */
    @GetMapping("/user/{userId}")
    public List<UserFamilyDTO> getUserFamiliesByUserId(@PathVariable Long userId) {
        // 用户只能查看自己的关联关系，管理员可以查看所有
        if (!StpUtil.getLoginIdAsString().equals(userId.toString()) && !permissionApplicationService.isSystemAdmin()) {
            return null; // 或抛出异常
        }
        
        return userFamilyApplicationService.getUserFamiliesByUserId(userId).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 根据家族树ID获取关联的用户
     * @param familyTreeId 家族树ID
     * @return 用户家族关联DTO列表
     */
    @GetMapping("/family-tree/{familyTreeId}")
    public List<UserFamilyDTO> getUserFamiliesByFamilyTreeId(@PathVariable Long familyTreeId) {
        // 检查当前用户是否有权限访问该家族树
        if (!permissionApplicationService.canAccessFamilyTree(familyTreeId)) {
            return null; // 或抛出异常
        }
        
        return userFamilyApplicationService.getUserFamiliesByFamilyTreeId(familyTreeId).stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 获取所有用户家族关联关系
     * @return 用户家族关联DTO列表
     */
    @GetMapping
    public List<UserFamilyDTO> getAllUserFamilies() {
        // 只有系统管理员可以获取所有关联关系
        if (!permissionApplicationService.isSystemAdmin()) {
            return null; // 或抛出异常
        }
        
        return userFamilyApplicationService.getAllUserFamilies().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 更新用户家族关联关系
     * @param id 关联ID
     * @param userFamilyDTO 用户家族关联DTO
     * @return 更新后的关联关系DTO
     */
    @PutMapping("/{id}")
    public SaResult updateUserFamily(@PathVariable Long id, @RequestBody UserFamilyDTO userFamilyDTO) {
        userFamilyDTO.setId(id);
        
        // 检查当前用户是否有权限管理该家族树
        if (!permissionApplicationService.canManageFamilyTree(userFamilyDTO.getFamilyTreeId())) {
            return SaResult.error("无权限执行此操作");
        }
        
        UserFamily userFamily = convertToDomain(userFamilyDTO);
        UserFamily updatedUserFamily = userFamilyApplicationService.updateUserFamily(userFamily);
        return SaResult.ok("更新成功").setData(convertToDTO(updatedUserFamily));
    }

    /**
     * 删除用户家族关联关系（从家族树中移除成员）
     * @param id 关联ID
     */
    @DeleteMapping("/{id}")
    public SaResult deleteUserFamily(@PathVariable Long id) {
        // 检查当前用户是否有权限管理该家族树
        // 需要先获取关联信息，检查权限
        UserFamily userFamily = userFamilyApplicationService.getUserFamilyById(id).orElse(null);
        if (userFamily == null) {
            return SaResult.error("关联关系不存在");
        }
        
        if (!permissionApplicationService.canManageFamilyTree(userFamily.getFamilyTreeId())) {
            return SaResult.error("无权限执行此操作");
        }
        
        userFamilyApplicationService.deleteUserFamily(id);
        return SaResult.ok("删除成功");
    }

    /**
     * 将UserFamilyDTO转换为UserFamily领域对象
     * @param userFamilyDTO 用户家族关联DTO
     * @return UserFamily领域对象
     */
    private UserFamily convertToDomain(UserFamilyDTO userFamilyDTO) {
        UserFamily userFamily = new UserFamily();
        userFamily.setId(userFamilyDTO.getId());
        userFamily.setUserId(userFamilyDTO.getUserId());
        userFamily.setFamilyTreeId(userFamilyDTO.getFamilyTreeId());
        userFamily.setRole(userFamilyDTO.getRole());
        userFamily.setCreateTime(userFamilyDTO.getCreateTime());
        return userFamily;
    }

    /**
     * 将UserFamily领域对象转换为UserFamilyDTO
     * @param userFamily UserFamily领域对象
     * @return 用户家族关联DTO
     */
    private UserFamilyDTO convertToDTO(UserFamily userFamily) {
        UserFamilyDTO userFamilyDTO = new UserFamilyDTO();
        userFamilyDTO.setId(userFamily.getId());
        userFamilyDTO.setUserId(userFamily.getUserId());
        userFamilyDTO.setFamilyTreeId(userFamily.getFamilyTreeId());
        userFamilyDTO.setRole(userFamily.getRole());
        userFamilyDTO.setCreateTime(userFamily.getCreateTime());
        return userFamilyDTO;
    }
}